package grape.attend.rest.group.mvc;

import cn.hutool.core.date.DateUtil;
import grape.attend.rest.classe.mapper.ClasseWebMapper;
import grape.attend.rest.group.form.ClasseAssignGroupForm;
import grape.attend.rest.group.form.GroupAssignClasseForm;
import grape.attend.rest.group.mapper.GroupClasseRelWebMapper;
import grape.attend.rest.group.mapper.GroupWebMapper;
import grape.attend.rest.group.vo.GroupAndClasseAllowClockVo;
import grape.attend.rest.group.vo.GroupAndClassesVo;
import grape.attend.rest.group.vo.GroupClasseRelVo;
import grape.attend.rest.user.mapper.UserClockWebMapper;
import grape.attend.service.group.api.IGroupClasseRelService;
import grape.attend.service.group.po.GroupClasseRel;
import grape.attend.service.user.api.IUserClockService;
import grape.attend.service.user.dto.GroupAndClasseDto;
import grape.attend.service.user.dto.GroupAndClassesDto;
import grape.attend.service.user.po.UserClock;
import grape.common.exception.ExceptionTools;
import grape.common.rest.mvc.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 考勤组与班次关系表，一对多 前端控制器
 * </p>
 *
 * @author yangwei
 * @since 2020-05-08
 */
@RestController
@RequestMapping("/attend/groupclasserel")
@Api(tags = "考勤组与班次关系表，一对多相关接口")
public class GroupClasseRelController extends BaseController<GroupClasseRelVo, GroupClasseRel> {

    @Autowired
    private GroupClasseRelWebMapper currentWebMapper;
    @Autowired
    private IGroupClasseRelService currentService;
    @Autowired
    private GroupWebMapper groupWebMapper;
    @Autowired
    private ClasseWebMapper classeWebMapper;

    @Autowired
    private IUserClockService iUserClockService;
    @Autowired
    private UserClockWebMapper userClockWebMapper;


    @ApiOperation("考勤组分配班次")
    @PreAuthorize("hasAuthority('groupClasseRel:single:groupAssignClasse')")
    @PostMapping("/group/assign/classe")
    @ResponseStatus(HttpStatus.CREATED)
    public Boolean groupAssignClasse(@RequestBody @Valid GroupAssignClasseForm cf) {
        currentService.groupAssignClasse(cf.getGroupId(),cf.getCheckedClasseIds(),cf.getUncheckedClasseIds(),cf.getIsLazyLoad());
        return true;
    }

    @ApiOperation("根据考勤组ID查询已分配的班次id")
    @PreAuthorize("hasAuthority('groupClasseRel:single:queryByGroupId')")
    @GetMapping("/group/{groupId}")
    @ResponseStatus(HttpStatus.OK)
    public List<String> queryByGroupId(@PathVariable String groupId) {
        List<GroupClasseRel> rels = currentService.getByGroupId(groupId);
        if (rels == null) {
            throw ExceptionTools.dataNotExistRE("数据不存在");
        }

        return rels.stream().map(item -> item.getClasseId()).collect(Collectors.toList());
    }

    @ApiOperation("清空考勤组下的所有班次")
    @PreAuthorize("hasAuthority('groupClasseRel:single:deleteByGroupId')")
    @DeleteMapping("/group/{groupId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public Boolean deleteByGroupId(@PathVariable String groupId) {
        boolean b = currentService.removeByGroupId(groupId);
        if (!b) {
            throw ExceptionTools.failRE("删除失败，可能要删除的数据不存在，请刷新数据再试");
        }
        return b;
    }


    @ApiOperation("班次分配考勤组")
    @PreAuthorize("hasAuthority('groupClasseRel:single:classeAssignGroup')")
    @PostMapping("/classe/assign/group")
    @ResponseStatus(HttpStatus.CREATED)
    public Boolean classeAssignGroup(@RequestBody @Valid ClasseAssignGroupForm cf) {
        currentService.classeAssignGroup(cf.getClasseId(),cf.getCheckedGroupIds(),cf.getUncheckedGroupIds(),cf.getIsLazyLoad());
        return true;
    }

    @ApiOperation("根据班次ID查询已分配的班次id")
    @PreAuthorize("hasAuthority('groupClasseRel:single:queryByClasseId')")
    @GetMapping("/classe/{classeId}")
    @ResponseStatus(HttpStatus.OK)
    public List<String> queryByClasseId(@PathVariable String classeId) {
        List<GroupClasseRel> rels = currentService.getByClasseId(classeId);
        if (rels == null) {
            throw ExceptionTools.dataNotExistRE("数据不存在");
        }
        return rels.stream().map(item -> item.getClasseId()).collect(Collectors.toList());
    }

    @ApiOperation("清空班次下的所有考勤组")
    @PreAuthorize("hasAuthority('groupClasseRel:single:deleteByClasseId')")
    @DeleteMapping("/classe/{classeId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public Boolean deleteByClasseId(@PathVariable String classeId) {
        boolean b = currentService.removeByClasseId(classeId);
        if (!b) {
            throw ExceptionTools.failRE("删除失败，可能要删除的数据不存在，请刷新数据再试");
        }
        return b;
    }

    @ApiOperation("查询当前登录用户的考勤组和班次,包括打卡信息")
    @PreAuthorize("hasAuthority('user')")
    @GetMapping("/groupAndClasseList")
    @ResponseStatus(HttpStatus.OK)
    public List<GroupAndClasseAllowClockVo> groupAndClasseList(@ApiIgnore String loginUserId, @NotNull(message = "是否昨日班次不能为空") Boolean isClasseYestoday) {
        List<GroupAndClasseDto> groupAndClasseDtos = currentService.getGroupAndClasseCurrentByUserId(loginUserId);
        if (isEmpty(groupAndClasseDtos)) {
            throw ExceptionTools.dataNotExistRE("数据不存在");
        }
        Date classeDate = new Date();
        if (isClasseYestoday) {
            classeDate = DateUtil.yesterday();
        }

        Date finalClasseDate = classeDate;
        List<GroupAndClasseAllowClockVo> result = new ArrayList<>(groupAndClasseDtos.size());
        UserClock userClock = null;

        GroupAndClasseDto groupAndClasseDto = null;
        GroupAndClasseDto groupAndClasseDtoNext = null;
        int size = groupAndClasseDtos.size();
        GroupAndClasseAllowClockVo groupAndClasseAllowClockVo = null;
        for (int i = 0; i < size; i++) {
            groupAndClasseDto = groupAndClasseDtos.get(i);

            if (i == size -1) {
                groupAndClasseDtoNext =groupAndClasseDtos.get(0);
            }else{
                groupAndClasseDtoNext =groupAndClasseDtos.get(i + 1);
            }
            userClock = iUserClockService.getClock(groupAndClasseDto.getGroup().getId(),groupAndClasseDto.getClasse().getId(),loginUserId, finalClasseDate);
            groupAndClasseAllowClockVo = new GroupAndClasseAllowClockVo();
            groupAndClasseAllowClockVo.setGroup(groupWebMapper.poToVo(groupAndClasseDto.getGroup()));
            groupAndClasseAllowClockVo.setClasse(classeWebMapper.poToVo(groupAndClasseDto.getClasse()));
            groupAndClasseAllowClockVo.setUserClock(userClockWebMapper.poToVo(userClock));
                    groupAndClasseAllowClockVo.setIsAllowOnClock(IUserClockService.isAllowOnClock(groupAndClasseDto.getGroup(), groupAndClasseDto.getClasse(), groupAndClasseDtoNext.getClasse(),groupAndClasseDtoNext.getGroup(),userClock, isClasseYestoday));
                    groupAndClasseAllowClockVo.setIsAllowOffClock(IUserClockService.isAllowOffClock(groupAndClasseDto.getGroup(), groupAndClasseDto.getClasse(), groupAndClasseDtoNext.getClasse(),groupAndClasseDtoNext.getGroup(), userClock, isClasseYestoday));
            result.add(groupAndClasseAllowClockVo);

        }
        return result;
    }

    @ApiOperation("查询当前登录用户的考勤组和班次")
    @PreAuthorize("hasAuthority('user')")
    @GetMapping("/groupAndClassesList")
    @ResponseStatus(HttpStatus.OK)
    public List<GroupAndClassesVo> groupAndClassesList(@ApiIgnore String loginUserId) {
        List<GroupAndClassesDto> groupAndClassesDtos = currentService.getGroupAndClassesCurrentByUserId(loginUserId);
        if (isEmpty(groupAndClassesDtos)) {
            throw ExceptionTools.dataNotExistRE("数据不存在");
        }
        return groupAndClassesDtos.stream().map(
                item -> new GroupAndClassesVo(
                        groupWebMapper.poToVo(item.getGroup())
                        ,item.getClasses().stream().map(classe -> classeWebMapper.poToVo(classe)).collect(Collectors.toList())
                )).collect(Collectors.toList());
    }
}
